//=======================================================================================
// d3dUtil.h by Frank Luna (C) 2008 All Rights Reserved.
//=======================================================================================

#ifndef D3DUTIL_H
#define D3DUTIL_H

// Let VC++ know we are compiling for WinXP and up.  This let's us use
// API functions specific to WinXP (e.g., WM_INPUT API).
#ifndef _WIN32_WINNT
#define _WIN32_WINNT   0x0600 // Vista
#endif

 
// Enable extra D3D debugging in debug builds if using the debug DirectX runtime.  
// This makes D3D objects work well in the debugger watch window, but slows down 
// performance slightly.
#if defined(DEBUG) || defined(_DEBUG)
	#ifndef D3D_DEBUG_INFO
	#define D3D_DEBUG_INFO
	#endif
#endif

#if defined(DEBUG) || defined(_DEBUG)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif


#include <d3dx11.h>
#include <dxerr.h>
#include <xnamath.h>
#include <D3Dcompiler.h>
#include <cassert>


//*****************************************************************************
// Convenience macro for releasing COM objects.
//*****************************************************************************

#define ReleaseCOM(x) { if(x){ x->Release();x = 0; } }


//*****************************************************************************
// Convenience functions.
//*****************************************************************************

// Converts ARGB 32-bit color format to ABGR 32-bit color format.
D3DX11INLINE UINT ARGB2ABGR(UINT argb)
{
	BYTE A = (argb >> 24) & 0xff;
	BYTE R = (argb >> 16) & 0xff;
	BYTE G = (argb >>  8) & 0xff;
	BYTE B = (argb >>  0) & 0xff;

	return (A << 24) | (B << 16) | (G << 8) | (R << 0);
}

// Returns random float in [0, 1).
D3DX11INLINE float RandF()
{
	return (float)(rand()) / (float)RAND_MAX;
}

// Returns random float in [a, b).
D3DX11INLINE float RandF(float a, float b)
{
	return a + RandF()*(b-a);
}

// Returns random vector on the unit sphere.
D3DX11INLINE XMVECTOR RandUnitVec3()
{
	XMVECTOR v = XMVectorSet(RandF(), RandF(), RandF(), 0.0f);
	v = XMVector3Normalize(v);
	return v;
}
 
template<typename T>
D3DX11INLINE T Min(const T& a, const T& b)
{
	return a < b ? a : b;
}

template<typename T>
D3DX11INLINE T Max(const T& a, const T& b)
{
	return a > b ? a : b;
}
 
template<typename T>
D3DX11INLINE T Lerp(const T& a, const T& b, float t)
{
	return a + (b-a)*t;
}

template<typename T>
D3DX11INLINE T Clamp(const T& x, const T& low, const T& high)
{
	return x < low ? low : (x > high ? high : x); 
}


//*****************************************************************************
// Constants
//*****************************************************************************

const float INFINITY = FLT_MAX;
const float PI       = 3.14159265358979323f;
const float MATH_EPS = 0.0001f;

const XMFLOAT4 WHITE(1.0f, 1.0f, 1.0f, 1.0f);
const XMFLOAT4 BLACK(0.0f, 0.0f, 0.0f, 1.0f);
const XMFLOAT4 RED(1.0f, 0.0f, 0.0f, 1.0f);
const XMFLOAT4 GREEN(0.0f, 1.0f, 0.0f, 1.0f);
const XMFLOAT4 BLUE(0.0f, 0.0f, 1.0f, 1.0f);
const XMFLOAT4 YELLOW(1.0f, 1.0f, 0.0f, 1.0f);
const XMFLOAT4 CYAN(0.0f, 1.0f, 1.0f, 1.0f);
const XMFLOAT4 MAGENTA(1.0f, 0.0f, 1.0f, 1.0f);

const XMFLOAT4 BEACH_SAND(1.0f, 0.96f, 0.62f, 1.0f);
const XMFLOAT4 LIGHT_YELLOW_GREEN(0.48f, 0.77f, 0.46f, 1.0f);
const XMFLOAT4 DARK_YELLOW_GREEN(0.1f, 0.48f, 0.19f, 1.0f);
const XMFLOAT4 DARKBROWN(0.45f, 0.39f, 0.34f, 1.0f);


#endif // D3DUTIL_H